package com.wmh.baseservice.user.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wmh.baseservice.admin.pojo.AdGoods;
import com.wmh.baseservice.admin.service.AdGoodsService;
import com.wmh.baseservice.common.annotation.parameterverify.ParameterVerify;
import com.wmh.baseservice.common.ex.ServiceException;
import com.wmh.baseservice.common.utils.CommUtil;
import com.wmh.baseservice.common.utils.UUIDUtil;
import com.wmh.baseservice.common.utils.page.pojo.PageInfo;
import com.wmh.baseservice.common.utils.page.pojo.PageResult;
import com.wmh.baseservice.common.utils.page.pojo.SortWay;
import com.wmh.baseservice.common.utils.page.util.PageUtil;
import com.wmh.baseservice.common.utils.returnbody.ResultCodeInfo;
import com.wmh.baseservice.common.utils.returnbody.ReturnBody;
import com.wmh.baseservice.merchant.pojo.*;
import com.wmh.baseservice.merchant.service.MerchantFreightTemplateService;
import com.wmh.baseservice.merchant.service.MerchantGoodsService;
import com.wmh.baseservice.merchant.service.MerchantVegetablePlotService;
import com.wmh.baseservice.merchant.service.MerchantVegetableService;
import com.wmh.baseservice.system.pojo.SysLocation;
import com.wmh.baseservice.system.service.SysLocationService;
import com.wmh.baseservice.user.pojo.UsShopCar;
import com.wmh.baseservice.user.pojo.UsVegetableOrder;
import com.wmh.baseservice.user.service.UsShopCarService;
import com.wmh.baseservice.user.service.UsVegetableOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author wmh generator
 * @since 2022-02-20
 */
@Api(tags = "用户端-购物车相关接口")
@RestController
@RequestMapping(value = "user/usShopCar", produces = "text/plain;charset=utf-8")
public class UsShopCarController {

    @Resource
    private UsShopCarService usShopCarService;
    @Resource
    private AdGoodsService adGoodsService;
    @Resource
    private MerchantGoodsService merchantGoodsService;
    @Resource
    private HttpServletRequest request;
    @Resource
    private MerchantVegetableService merchantVegetableService;
    @Resource
    private UsVegetableOrderService usVegetableOrderService;
    @Resource
    private MerchantVegetablePlotService merchantVegetablePlotService;
    @Resource
    private MerchantFreightTemplateService merchantFreightTemplateService;
    @Resource
    private SysLocationService sysLocationService;

    @ApiOperation("添加商品到购物车")
    @PostMapping("add")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataTypeClass = Long.class, name = "id", value = "商品id", required = false),
            @ApiImplicitParam(paramType = "query", dataTypeClass = Integer.class, name = "type", value = "1平台商品 2商家商品", required = false),
            @ApiImplicitParam(paramType = "query", dataTypeClass = Integer.class, name = "status", value = "1添加 -1减少", required = false),
            @ApiImplicitParam(paramType = "query", dataTypeClass = Long.class, name = "merchantId", value = "商家id", required = false),
    })
    @ParameterVerify(notNull = {"type", "id", "status"})
    public String add(Long id, Integer type, Integer status, Long merchantId, Integer specialType, Long plotId) {
        Long usId = (Long) request.getAttribute("usId");
        AdGoods adGoods;
        MerchantGoods merchantGoods;
        MerchantVegetable merchantVegetable = null;
        if (type == 1) {
            adGoods = adGoodsService.getByIdForUpdate(id);
            if (!CommUtil.checkNull(adGoods) || adGoods.getStatus() != 0) {
                return ReturnBody.error("商品不存在或已下架");
            }
        } else if (type == 2) {
            merchantGoods = merchantGoodsService.getByIdForUpdate(id);
            if (!CommUtil.checkNull(merchantGoods) || merchantGoods.getStatus() != 0) {
                return ReturnBody.error("商品不存在或已下架");
            }
        } else if (type == 3) {
            merchantVegetable = merchantVegetableService.getByIdForUpdate(id);
            if (!CommUtil.checkNull(merchantVegetable) || merchantVegetable.getStatus() != 0) {
                return ReturnBody.error("果蔬不存在或已下架");
            }
        }

        QueryWrapper<UsShopCar> eq = new QueryWrapper<UsShopCar>().eq(UsShopCar.GOODS_ID, id).eq(UsShopCar.US_ID, usId)
                .eq(UsShopCar.TYPE, type).eq(UsShopCar.MERCHANT_ID, merchantId);
        if (CommUtil.checkNull(specialType)) {
            eq.eq(UsShopCar.SPECIAL_TYPE, specialType);
        }
        if (CommUtil.checkNull(plotId)) {
            eq.eq(UsShopCar.PLOT_ID, plotId);
        }
        UsShopCar usShopCar = usShopCarService.getOneForUpdate(eq);
        if (CommUtil.checkNull(usShopCar)) {
            if (status == -1) {
                usShopCar.setCount(Math.max(usShopCar.getCount() - 1, 0));
                //采摘情况下,重量小于1斤时，用户点击减少，直接减为0
                if (type == 3 && usShopCar.getCount() < 1 && specialType == 0) {
                    usShopCar.setCount(0.00);
                }
            } else {
                usShopCar.setCount(usShopCar.getCount() + 1);
//                if (type == 3) {
//                    if (specialType == 0 && merchantVegetable.getInventory() != -1) {
//                        //判断采摘库存是否足够
//                        if (merchantVegetable.getInventory() < usShopCar.getCount()) {
//                            return ReturnBody.error("库存不足");
//                        }
//                    } else if (specialType == 1 && merchantVegetable.getGrowInventory() != -1) {
//                        if (merchantVegetable.getGrowInventory() < usShopCar.getCount()) {
//                            return ReturnBody.error("库存不足");
//                        }
//                    }
//                }
            }
            if (!usShopCarService.updateById(usShopCar)) {
                return ReturnBody.error(ResultCodeInfo.SERVICE_EXCEPTION);
            }
        } else {
            //查询库存是否足够
            usShopCar = new UsShopCar().setUsId(usId).setType(type).setCount(1D).setGoodsId(id);
            if (CommUtil.checkNull(merchantId)) {
                usShopCar.setMerchantId(merchantId);
            }
            if (CommUtil.checkNull(plotId)) {
                usShopCar.setPlotId(plotId);
            }
            if (CommUtil.checkNull(specialType)) {
                usShopCar.setSpecialType(specialType);
//                if (status == 1) {
//                    if (specialType == 0 && merchantVegetable.getInventory() != -1) {
//                        //判断采摘库存是否足够
//                        if (merchantVegetable.getInventory() < usShopCar.getCount()) {
//                            return ReturnBody.error("库存不足");
//                        }
//                    } else if (specialType == 1 && merchantVegetable.getGrowInventory() != -1) {
//                        if (merchantVegetable.getGrowInventory() < usShopCar.getCount()) {
//                            return ReturnBody.error("库存不足");
//                        }
//                    }
//                }
            }
            if (!usShopCarService.save(usShopCar)) {
                return ReturnBody.error(ResultCodeInfo.SERVICE_EXCEPTION);
            }
        }
        return ReturnBody.success(totalPrice(3, usId, plotId, null).get("amount"));
    }

    @ApiOperation("修改购物车数量(果蔬采摘)")
    @PostMapping("changeCountVegetable")
    public String changeCountVegetable(Long id, Long plotId, Double count) {
        Long usId = (Long) request.getAttribute("usId");
        UsShopCar usShopCar = usShopCarService.getOneForUpdate(new QueryWrapper<UsShopCar>().eq(UsShopCar.US_ID, usId).eq(UsShopCar.PLOT_ID, plotId)
                .eq(UsShopCar.GOODS_ID, id).eq(UsShopCar.SPECIAL_TYPE, 0));
        if (!CommUtil.checkNull(usShopCar)) {
            return ReturnBody.error("修改采摘购物车重量异常，请退出页面后重试");
        }
        usShopCar.setCount(count);
        if (!usShopCarService.updateById(usShopCar)) {
            return ReturnBody.error(ResultCodeInfo.SERVICE_EXCEPTION);
        }
        return ReturnBody.success(totalPrice(3, usId, plotId, null).get("amount"));
    }

    @ApiOperation("删除购物车")
    @PostMapping("delete")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataTypeClass = Long.class, name = "ids", value = "购物车id数组", required = false),
    })
    @ParameterVerify(notNull = "ids")
    public String delete(String ids) {
        Long usId = (Long) request.getAttribute("usId");
        JSONArray array = JSONArray.parseArray(ids);
        array.forEach(item -> {
            UsShopCar usShopCar = usShopCarService.getByIdForUpdate(Long.parseLong(item.toString()));
            if (CommUtil.checkNull(usShopCar) && usShopCar.getUsId().equals(usId)) {
                if (!usShopCarService.removeById(usShopCar.getId())) {
                    throw new ServiceException();
                }
            }
        });
        return ReturnBody.success();
    }

    @ApiOperation("购物车列表")
    @PostMapping("list")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataTypeClass = Long.class, name = "id", value = "id", required = false),
    })
    public String list(PageInfo pageInfo, Integer type, Long plotId) {
        Long usId = (Long) request.getAttribute("usId");
        PageResult<UsShopCar> pageResult = new PageResult<>();
        if (CommUtil.checkNull(pageInfo.getPageSize())) {
            pageInfo.setTimeScreen("create_time");
            pageInfo.setDefaultSort("create_time", SortWay.DESC);
            //执行分页辅助工具
            pageResult = new PageUtil<UsShopCar>(pageInfo).startPage((page, queryWrapper) -> {
                queryWrapper.eq(UsShopCar.US_ID, usId);
                if (CommUtil.checkNull(type)) {
                    queryWrapper.eq(UsShopCar.TYPE, type);
                }
                usShopCarService.page(page, queryWrapper);
            });
        } else {
            QueryWrapper<UsShopCar> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(UsShopCar.US_ID, usId);
            if (CommUtil.checkNull(type)) {
                queryWrapper.eq(UsShopCar.TYPE, type);
            }
            if (CommUtil.checkNull(plotId)) {
                queryWrapper.eq(UsShopCar.PLOT_ID, plotId);
            }
            queryWrapper.ne(UsShopCar.COUNT, 0);
            List<UsShopCar> usShopCarList = usShopCarService.list(queryWrapper);
            pageResult.setList(usShopCarList);
        }
        pageResult.getList().forEach(item -> {
            switch (item.getType()) {
                case 1:
                    AdGoods adGoods = adGoodsService.getById(item.getGoodsId());
                    item.setAvatar(adGoods.getAvatar());
                    item.setPrice(adGoods.getPrice());
                    item.setTitle(adGoods.getTitle());
                    break;
                case 2:
                    MerchantGoods merchantGoods = merchantGoodsService.getById(item.getGoodsId());
                    item.setAvatar(merchantGoods.getAvatar());
                    item.setPrice(merchantGoods.getPrice());
                    item.setTitle(merchantGoods.getTitle());
                    break;
                case 3:
                    MerchantVegetable merchantVegetable = merchantVegetableService.getById(item.getGoodsId());
                    item.setAvatar(merchantVegetable.getAvatar());
                    item.setPrice(item.getSpecialType() == 0 ? merchantVegetable.getPrice() : merchantVegetable.getGrowPrice());
                    item.setTitle(merchantVegetable.getTitle());
                    item.setHasCourier(merchantVegetable.getHasCourier());
            }
        });
        return ReturnBody.success(pageResult);
    }

    @ApiOperation("购物车结算")
    @PostMapping("settlement")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataTypeClass = Integer.class, name = "type", value = "1平台商品 2商家商品 3果蔬商品", required = false),
    })
    @ParameterVerify(notNull = "type")
    public String settlement(Long plotId, Long merchantId, Integer type, String remark, Integer hasTake) {
        final int[] error = {0};
        Long usId = (Long) request.getAttribute("usId");
        switch (type) {
            case 1:
                //平台商品
                break;
            case 2:
                //商家商品
                break;
            case 3:
                //果蔬商品
                List<UsShopCar> usShopCarList = usShopCarService.listForUpdate(new QueryWrapper<UsShopCar>()
                        .eq(UsShopCar.PLOT_ID, plotId).eq(UsShopCar.US_ID, usId).ne(UsShopCar.COUNT, 0));
                if (usShopCarList.size() == 0) {
                    return ReturnBody.error("您还没有添加果蔬摘种商品到购物车哦");
                }
                //查询用户短时间内是否已提交过订单
                int orderCount = usVegetableOrderService.queryShortOrder(usId);
                if (orderCount != 0) {
                    return ReturnBody.error("您刚刚已提交过订单，为保证正常交易，请等待半分钟后再提交");
                }
                String orderNum = merchantVegetableService.batchSubOrder(usShopCarList, remark, hasTake);
                return ReturnBody.success(orderNum);
        }
        return ReturnBody.success();
    }

    @ApiOperation("购物车总价")
    @PostMapping("shopCarTotalAmount")
    public String shopCar(Long plotId, String area) {
        Long usId = (Long) request.getAttribute("usId");
        JSONObject object = new JSONObject(true);
        //查询区域id
        SysLocation sysLocation = new SysLocation();
        if (CommUtil.checkNull(area)) {
            sysLocation = sysLocationService.getOne(new QueryWrapper<SysLocation>().eq(SysLocation.NAME, area));
            if (!CommUtil.checkNull(sysLocation)) {
                return ReturnBody.error("获取地址信息错误");
            }
        }
        if (CommUtil.checkNull(sysLocation.getId())) {
            object.put("amount", totalPrice(3, usId, plotId, String.valueOf(sysLocation.getId())));
        } else {
            object.put("amount", totalPrice(3, usId, plotId, null).get("amount"));
        }
        MerchantVegetablePlot merchantVegetablePlot = merchantVegetablePlotService.getById(plotId);
        if (CommUtil.checkNull(merchantVegetablePlot)) {
            //购物车处联系的是土地原商家，如果是联系具体区域商家需要用户点击果蔬详情进去后联系
            object.put("merchantId", merchantVegetablePlot.getRawMerchantId());
            object.put("plotName", merchantVegetablePlot.getPlotName());
            object.put("plotAvatar", merchantVegetablePlot.getAvatar());
        }
        return ReturnBody.success(object);
    }

    public Map<String, Object> totalPrice(Integer type, Long usId, Long plotId, String addressId) {
        Map<String, Object> map = new HashMap<>();
        final BigDecimal[] totalAmount = {BigDecimal.ZERO};
        List<BigDecimal> freight = new ArrayList<>();
        List<UsShopCar> usShopCarList = usShopCarService.listForUpdate(new QueryWrapper<UsShopCar>().eq(UsShopCar.US_ID, usId)
                .eq(UsShopCar.PLOT_ID, plotId));
        usShopCarList.forEach(item -> {
            MerchantVegetable merchantVegetable = merchantVegetableService.getByIdForUpdate(item.getGoodsId());
            if (CommUtil.checkNull(merchantVegetable)) {
                BigDecimal multiply;
                if (item.getSpecialType() == 0) {
                    multiply = merchantVegetable.getPrice().multiply(BigDecimal.valueOf(item.getCount()));
                    //快递运费
                    if (CommUtil.checkNull(merchantVegetable.getHasCourier()) && merchantVegetable.getHasCourier() == 1) {
                        //查询运费模板
                        if (CommUtil.checkNull(merchantVegetable.getFreightId()) && CommUtil.checkNull(addressId)) {
                            MerchantFreightTemplate freightTemplate = merchantFreightTemplateService.getById(merchantVegetable.getFreightId());
                            boolean contains = Arrays.asList(freightTemplate.getLocationIds().split(",")).contains(addressId);
                            if (contains) {
                                //计算运费
                                freight.add(freightTemplate.getAreaPrice());
                            } else {
                                freight.add(freightTemplate.getDefaultPrice());
                            }
                        }
                    }
                } else {
                    multiply = merchantVegetable.getGrowPrice().multiply(BigDecimal.valueOf(item.getCount()));
                }
                totalAmount[0] = totalAmount[0].add(multiply);
            }
        });
        //运费最大值
        if (CommUtil.checkNull(addressId)) {
            BigDecimal max = freight.stream().reduce(freight.get(0), BigDecimal::max);
            map.put("max", max);
        }
        map.put("amount", totalAmount[0].setScale(2, BigDecimal.ROUND_DOWN));
//        map.put("freightAmount", freightAmount[0].setScale(2, BigDecimal.ROUND_DOWN));
        return map;
    }
}
